import sys

# A debugging method
debugOn = False

def debug(message):
	if debugOn:
		sys.stderr.write(message+"\n")
		sys.stderr.flush()

def userMsg(message):
	sys.stderr.write(message+"\n")
	sys.stderr.flush()


# Make some constants for the piece codes

class Pos(object):
	def __init__(self,arg1,arg2=None,arg3=None):
		if arg2 is None:
			loc = arg1
		else:
			loc = (arg1,arg2,arg3)

		if type(loc) == tuple: # if we got x, y and t
			self.x = int(loc[0])
			self.y = int(loc[1])
			self.t = int(loc[2])
			self.file = chr(97+self.x)
			self.rank = str(self.y+1)
		elif type(loc) in [str, unicode]: # if we got math notation string a1t0->h8t999
			self.file = loc[0]
			self.rank = loc[1]
			self.t = int(loc[3:])
			self.x = ord(self.file.lower())-97
			self.y = int(self.rank)-1
		else:
			raise TypeError

	def isOnBoard(self):
		return ((0<=self.x and self.x<8 and 0<=self.y and self.y<8) and
				(self.t >= 0))

	def __eq__(self,other):
		return ((self.x == other.x) and (self.y == other.y) and (self.t == other.t))

	def __hash__(self):
		"""Function to allow positions to be used as keys in a dictionary"""
		return (self.t*64)+(self.x*8)+self.y

	def __str__(self):
		return "%s%st%s" % (self.file, self.rank, self.t)

	def __repr__(self):
		return "Pos(\"%s\")" % str(self)

#####################################################
#				MOVE OBJECT							#
#####################################################

class Move(object):
	"""
	Immutable object representing a pair of positions

	This is a dumb object which is basically a data type
	"""
	def __init__(self, start, end):
		self.start = start
		self.end = end

		self.isFuture =	(start.t < end.t)
		self.isPast =	(start.t > end.t)
		self.isPresent =	(start.t == end.t)

	def __getitem__(self, *args, **kwargs):
		"""For indexing, treat the Move object as a tuple of 2 Pos objects"""
		return (self.start,self.end).__getitem__(*args,**kwargs)

	def __str__(self):
		return "%s%s" % (self.start,self.end)

	def __eq__(self,other):
		return ((self.start == other.start) and (self.end == other.end))


class Result(object):
	def __init__(self, value, message):
		self.value = value
		self.message = message
	
	def __nonzero__(self):
		return bool(self.value)


#====================================================================
#                    UNIT TESTS
#====================================================================
import unittest

class TestPos(unittest.TestCase):

#    def setUp(self):

	def test_creation(self):
		# Make sure the same piece made with different args are the same
		p1 = Pos("a1t0")
		p2 = Pos(0,0,0)
		p3 = Pos((0,0,0))
		self.assertEqual(p1, p2)
		self.assertEqual(p1, p3)
		self.assertEqual(p2, p3)

		# should raise an exception if given an int, list, float etc
		self.assertRaises(TypeError, Pos, 3)
		self.assertRaises(TypeError, Pos, [1,2,3])
		self.assertRaises(TypeError, Pos, 4.5)

#		self.assertTrue()
	def test_eq(self):
		# Pieces with the same position should be the same
		p1 = Pos("c2t0")
		p2 = Pos("c2t0")
		self.assertTrue(p1==p2)

		# if positions are only varied by time, they are still different
		p1 = Pos("c2t0")
		p2 = Pos("c2t1")
		self.assertFalse(p1==p2)


if __name__ == '__main__':
	unittest.main()

